﻿// Inner Fire 游戏引擎库
// DirectX 基础工具类
//
// Copyright (c) 2025 by 尔西大帝. All rights reserved.
//
// 把DxUtils分离出来，不要每次core改动都编译。
//
// Author: 尔西大帝
// Email: 2670613871@qq.com
// Created: 2025-03-13

#pragma once

#include <DirectXMath.h>
#include <EASTL/vector.h>
#include <d3d12.h>
#include <d3dx12.h>
#include <dxgi.h>
#include <functional>
#include <memory>
#include <string>
#include <wrl/client.h>

using Microsoft::WRL::ComPtr;

namespace ifire::dx {

/// <summary>
/// 用于DirectX的工具类。处理常用的工具。
/// </summary>
class DxUtils {
public:
  // 载入一个已经编译好的Shader
  static ComPtr<ID3DBlob> LoadShader(const std::string& filename);

  // 对Shader进行编译
  static ComPtr<ID3DBlob> CompileShader(const std::string& filename,
      const D3D_SHADER_MACRO* defines, const std::string& entry_point,
      const std::string& target);
  static ComPtr<ID3DBlob> CompileOrLoadShader(const std::string& filename,
      const D3D_SHADER_MACRO* defines, const std::string& entry_point,
      const std::string& target);

  // 计算缓冲区的大小，需要和256字节对齐
  constexpr static size_t CalcConstantBufferSize(size_t origin_byte_size) {
    return (origin_byte_size + 255) & ~255;
  }

  static ComPtr<ID3D12Resource> CreateDefaultBuffer(ID3D12Device* device,
      ID3D12GraphicsCommandList* cmd_list, const void* data, UINT64 data_size,
      ComPtr<ID3D12Resource>& upload_buffer);

  // 设置输出的流（此函数会输出错误信息）
  void SetOutputStream(std::function<void(std::string)> func);

  // 输出日志/错误信息
  void Log(const std::string& msg);

  // 获得一个合局的ID
  static std::uint64_t ObtainInstancedId();

  // 检查一个键是否被按下
  bool IsKeyDown(int vkeyCode);
  //
  // 获得MSAA配置
  //
  static void CheckMsaa(ID3D12Device* device);
  inline static UINT GetMsaaSampleCount() { return msaa_enable_ ? 4 : 1; }
  inline static UINT GetMsaaSampleQuality() {
    return msaa_enable_ ? (msaa_quality_ - 1) : 0;
  }
  inline static bool Get4xMsaaState() { return msaa_enable_; }
  inline static void Set4xMsaaState(bool value) { msaa_enable_ = value; }

private:
  // 用于Msaa
  static bool msaa_enable_;  // 4X MSAA 是否启用
  static UINT msaa_quality_; // 4X MSAA 质量级别
};

} // namespace ifire::dx